<?php
declare(strict_types=1);

namespace ExpressionEngine\VariableEngine;

use Contract\Exceptions\ValidationException;
use ExpressionEngine\VariableEngine\Enum\VariableEnum;

class VariableLexical
{
    protected VariableNode $variableNode;

    public function __construct(VariableNode $variableNode)
    {
        $this->variableNode = $variableNode;
    }

    /**
     * @param string $variable
     * @return void
     * @throws ValidationException
     */
    protected function validate(string $variable): void
    {
        if (empty($variable)) {
            throw new ValidationException('variable is empty');
        }
        $words = explode('.', $variable);
        foreach ($words as $word) {
            if (strcmp($word[0], '') == 0) {
                throw new ValidationException('word is empty');
            }

            if ((str_contains($word, '[') || str_contains($word, ']')) && !preg_match('/^\[.+\]$/', $word)) {
                throw new ValidationException('word:' . $word . ' is not valid');
            }
            if (preg_match('/^\[.+\]$/', $word) && !preg_match('/^\[([^\[\]\=]+)=([^\[\]\=]+)\]$/', $word)) {
                throw new ValidationException('word:' . $word . ' is not valid');
            }
        }
    }

    /**
     * @param string $variable
     * @return array
     * @throws ValidationException
     */
    public function parse(string $variable): array
    {
        $this->validate($variable);
        $words = explode('.', $variable);
        $variableTree = [];
        foreach ($words as $key => $word) {
            if (!preg_match('/^\[.+\]$/', $word)) {
                $variableTree[] = $this->variableNode->getNode(VariableEnum::NODE_KEY, [$word]);
            } else {
                preg_match('/^\[([^\[\]\=]+)=([^\[\]\=]+)\]$/', $word, $matches);
                $variableTree[] = $this->variableNode->getNode(VariableEnum::NODE_SEARCH, [$matches[1], $matches[2]]);
            }
        }
        return $variableTree;
    }

}